#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int INF=0x3f3f3f3f;
double x[105];
double y[105];
double z[105];
double r[105];
int n;
double g[105][105];
double lowcost[105];
bool vis[105];
void init(){
    memset(x,0.0,sizeof(x));
    memset(y,0.0,sizeof(y));
    memset(z,0.0,sizeof(z));
    memset(g,0.0,sizeof(g));
}
double point_dis(int i,int j){
    return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])+(z[i]-z[j])*(z[i]-z[j]))-r[i]-r[j];
}
double prim(){
    memset(lowcost,0,sizeof(lowcost));
    memset(vis,false,sizeof(vis));
    double ans=0;
    double Min=INF;
    int pos=1;
    vis[pos]=true;
    for(int i=1;i<=n;i++){
        if(i!=pos){
            lowcost[i]=g[pos][i];
        }
    }
    for(int i=1;i<n;i++){
        Min=INF;
        //找到相邻最小点
        for(int j=1;j<=n;j++){
            if(!vis[j] && lowcost[j]<Min){
                Min=lowcost[j];
                pos=j;
            }
        }
        ans+=Min;
        vis[pos]=true;
        //更新lowcost
        for(int j=1;j<=n;j++){
            if(!vis[j] && lowcost[j]>g[pos][j]){
                lowcost[j]=g[pos][j];
            }
        }
    }
    return ans;
}
int main(void){
    //freopen("data.txt","r",stdin);
    while(~scanf("%d",&n) && n){
        init();
        for(int i=1;i<=n;i++){
            scanf("%lf%lf%lf%lf",&x[i],&y[i],&z[i],&r[i]);
        }
        //建图
        for(int i=1;i<=n-1;i++){
            for(int j=i+1;j<=n;j++){
                double dis=point_dis(i,j);
                if(dis<=0){
                    g[i][j]=g[j][i]=0;
                }
                else{
                    g[i][j]=g[j][i]=dis;
                }
            }
        }
        double ans=prim();
        //用g++ 输出double要用%f
        printf("%.3f\n",ans);
    }
    return 0;
}
